package cn.zyjw.service.impl;

import cn.zyjw.constant.LoginConstant;
import cn.zyjw.entity.SysUser;
import cn.zyjw.mapper.SysPrivilegeMapper;
import cn.zyjw.mapper.SysUserMapper;
import cn.zyjw.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserServiceDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysPrivilegeMapper sysPrivilegeMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String loginType = request.getParameter("login_type");
        if (StringUtils.isEmpty(loginType)) {
            throw new AuthenticationServiceException("登录类型不能为null");
        }

        String grantType = request.getParameter("grant_type");

        switch (loginType) {
            case LoginConstant.ADMIN_TYPE:
                return loadAdminUserInfoByUserName(userName, grantType);
            case LoginConstant.MEMBER_TYPE:
                return loadMemberUserInfoByUserName(userName, grantType);
            default:
                throw new AuthenticationServiceException("暂不支持的登录方式:" + loginType);
        }
    }

    /**
     * 会员登录
     */
    private UserDetails loadMemberUserInfoByUserName(String userName, String grantType) {
        cn.zyjw.entity.User member = null;
        if (StringUtils.isNotBlank(grantType) && LoginConstant.REFRESH_TOKEN.equalsIgnoreCase(grantType)) {
            member = userMapper.selectById(userName);
        } else {
            member = userMapper.queryMemberByNameOrMobile(userName);
        }
        if (member == null) {
            throw new InvalidGrantException("用户名密码错误");
        }
        return new User(
                member.getId().toString(),
                member.getPassword(),
                member.getStatus() == 1,
                true,
                true,
                true,
                Lists.newArrayList(new SimpleGrantedAuthority("ROLE_USER"))
        );
    }

    /**
     * 后台人员登录
     *
     * @return
     */
    private UserDetails loadAdminUserInfoByUserName(String userName, String grantType) {
        SysUser sysUser = null;
        if (StringUtils.isNotBlank(grantType) && LoginConstant.REFRESH_TOKEN.equalsIgnoreCase(grantType)) {
            sysUser = sysUserMapper.selectById(userName);
        } else {
            sysUser = sysUserMapper.queryAdminByUserName(userName);
        }
        if (sysUser == null) {
            throw new InvalidGrantException("用户名密码错误");
        }
        Long id = sysUser.getId();
        return new User(
                id.toString(),
                sysUser.getPassword(),
                sysUser.getStatus() == 1,
                true,
                true,
                true,
                getSysUserPermissions(id));
    }

    private Set<SimpleGrantedAuthority> getSysUserPermissions(Long id) {
        String code = sysUserMapper.queryCodeByUserId(id);
        Set<String> privileges = null;
        if (LoginConstant.ROLE_ADMIN.equals(code)) {//管理员登录获取全部权限
            privileges = sysPrivilegeMapper.queryAllPermissions();
        }
        privileges = sysPrivilegeMapper.queryPermissionByUserId(id);
        if (privileges == null || privileges.isEmpty()) {
            return Collections.EMPTY_SET;
        }
        return privileges.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
    }


}
